﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;

namespace KgUtils.Wpf.BaseClasses
{
    public class BaseBE<T> : ICloneable, INotifyPropertyChanged, IEditableObject where T : BaseBE<T>, IEntity
    {
        private bool _isModified;
        private bool _isSelected;
        private DateTime _dateCreation;
        private DateTime _dateMaj;
        private string _userMaj;

        /// <summary>
        /// indique si l'objet à été modifié
        /// </summary>
        public bool IsModified
        {
            get { return _isModified; }
            set { _isModified = value; OnPropertyChanged("IsModified"); }
        }

        /// <summary>
        /// Propriété indiquant si l'objet est sélectionné
        /// </summary>
        public bool IsSelected
        {
            get { return _isSelected; }
            set { _isSelected = value; OnPropertyChanged("IsSelected"); }
        }

        /// <summary>
        /// Date de création
        /// </summary>
        public DateTime DateCreation
        {
            get { return _dateCreation; }
            set { _dateCreation = value; OnPropertyChanged("DateCreation"); }
        }

        /// <summary>
        /// Date de mise à jour
        /// </summary>
        public DateTime DateMaj
        {
            get { return _dateMaj; }
            set { _dateMaj = value; OnPropertyChanged("DateMaj"); }
        }

        /// <summary>
        /// Utilisateur Maj
        /// </summary>
        public string UtilisateurMaj
        {
            get { return _userMaj; }
            set { _userMaj = value; OnPropertyChanged("UtilisateurMaj"); }
        }

        #region Editable useful properties
        protected T ClonedItem;
        #endregion

        public BaseBE()
        {
            if (this.DateCreation == DateTime.MinValue)
                this.DateCreation = DateTime.Now;
            if (this.DateMaj == DateTime.MinValue)
                this.DateMaj = DateTime.Now;

            this.IsModified = false;
        }

        #region INotifyPropertyChanged Membres

        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        protected virtual void OnPropertyChanged(params string[] propertyNames)
        {
            foreach (string propertyName in propertyNames)
                this.OnPropertyChanged(propertyName);
        }

        #endregion

        #region IEditableObject
        public virtual void BeginEdit()
        {
            // clone de l'objet
            this.ClonedItem = (T)this.Clone();
        }

        public virtual void CancelEdit()
        {
            this.DateMaj = this.ClonedItem.DateMaj;
            this.UtilisateurMaj = this.ClonedItem.UtilisateurMaj;

            this.IsSelected = this.ClonedItem.IsSelected;
            this.IsModified = false;

            // on RAZ le clone
            this.ClonedItem = null;
        }

        public virtual void EndEdit()
        {
            this.ClonedItem = null;
        }

        /// <summary>
        /// Valide les changements de l'objet, mais reste en mode édition.
        /// </summary>
        public virtual void CommitEdit()
        {
            this.EndEdit();
            this.BeginEdit();
        }
        #endregion

        public object Clone()
        {
            return this.MemberwiseClone();
        }
    }
}
